mod model;
mod traits;
mod utils;
use crate::traits::FilterLibImportTrait;
use clap::{Arg, ArgAction, Command};
use common::file_system::write_to_file;
use common::file_system::{deserialize_json, deserialize_toml};
use common::model::ProjectConfig;
use std::fs;
use std::path::Path;

use model::ApiDesc;
use utils::{generate_function, init_import};

const COMMAND_NAME: &str = "gen_api";
const NO_LIB_IMPORT_ERR_MSG: &str =
    "未配置gen_api的lib_imports，这会导致生成的代码由于没有import必要的依赖而出错";

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let matches = Command::new(COMMAND_NAME)
        .version("1.0")
        .author("caozongying<zongying_cao@163.com>")
        .about("caozongying_cao<zongying_cao@163.com> is the author of gen api")
        .arg(
            Arg::new("api")
                .short('i')
                .long("api")
                .value_name("API_DOC_PATH")
                .help("api的json文件路径")
                .action(ArgAction::Set),
        )
        .arg(
            Arg::new("module")
                .short('m')
                .long("module")
                .value_name("MODULE_FILE_PATH")
                .help("模块定义路径")
                .action(ArgAction::Set),
        )
        .arg(
            Arg::new("module_file")
                .short('n')
                .long("module_file")
                .value_name("MODULE_FILE")
                .help("输出的typescript模块文件的路径及名称")
                .action(ArgAction::Set),
        )
        .get_matches();

    let api_path = matches.get_one::<String>("api").expect("参数api未定义");
    let module_path = matches
        .get_one::<String>("module")
        .expect("参数module未定义");
    let module_file_path = matches
        .get_one::<String>("module_file")
        .expect("参数module_file未定义");

    let api_desc: ApiDesc = deserialize_json(
        &fs::read_to_string(api_path)
            .unwrap_or_else(|_| panic!("提供的api.json文件路径不正确:{:?}", api_path)),
    )?;

    let module_config = deserialize_toml::<ProjectConfig>(
        &fs::read_to_string(module_path)
            .unwrap_or_else(|_| panic!("提供的模块定义文件路径不正确:{:?}", module_path)),
    )?;

    let mut functions = String::new();

    for api in &api_desc.apis {
        functions.push_str(&generate_function(api)?);
    }

    write_to_file(
        Path::new(module_file_path),
        &format!(
            r#"
{}

"#,
            &functions,
        ),
    )
    .unwrap_or_else(|_| panic!("生成api.ts文件出错，路径:{}", module_file_path));

    if let Some(lib_imports) = module_config
        .lib_imports
        .as_ref()
        .map(|_lib_import| _lib_import.filter(COMMAND_NAME))
    {
        if !lib_imports.is_empty() {
            init_import(module_file_path, &lib_imports)?;
        }
        return Ok(());
    }

    eprintln!("{}", NO_LIB_IMPORT_ERR_MSG);
    Ok(())
}
